package com.chinaunicom.order.infrastructure.repository;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.chinaunicom.common.exception.BusinessException;
import com.chinaunicom.order.domain.model.entity.CreateOrderEntity;
import com.chinaunicom.order.domain.model.entity.OrderEntity;
import com.chinaunicom.order.domain.model.valobj.OrderStatus;
import com.chinaunicom.order.domain.model.valobj.PayStatus;
import com.chinaunicom.order.domain.repository.IOrderRepository;
import com.chinaunicom.order.infrastructure.database.mapper.OrderItemMapper;
import com.chinaunicom.order.infrastructure.database.mapper.OrderMapper;
import com.chinaunicom.order.infrastructure.database.po.OrderItemPO;
import com.chinaunicom.order.infrastructure.database.po.OrderPO;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author guomenghuai
 * @date 2024/1/15
 * @Description
 */
@Repository
public class OrderRepository implements IOrderRepository {

    @Resource
    private OrderMapper orderMapper;

    @Resource
    private OrderItemMapper orderItemMapper;

    @Override
    public OrderEntity getByOrderId(Long orderId) {
        OrderPO orderPO = orderMapper.selectById(orderId);

        OrderEntity orderEntity = new OrderEntity();
        if (orderPO == null) {
            return orderEntity;
        }

        BeanUtils.copyProperties(orderPO, orderEntity);
        orderEntity.setOrderStatus(OrderStatus.getByCode(orderPO.getStatus()));
        orderEntity.setPayStatus(PayStatus.getByCode(orderPO.getPayStatus()));
        return orderEntity;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveOrder(CreateOrderEntity createOrderEntity) {
        OrderPO orderPO = buildOrder(createOrderEntity);
        orderMapper.insert(orderPO);

        List<OrderItemPO> orderItemList = buildOrderItem(createOrderEntity, orderPO.getOrderId());
        boolean result = false;
        for (OrderItemPO orderItemPO : orderItemList) {
            int count = orderItemMapper.insert(orderItemPO);
            result = count > 0;
        }

        if (!result) {
            throw new BusinessException("插入订单项失败");
        }
        return orderPO.getOrderId();
    }

    private List<OrderItemPO> buildOrderItem(CreateOrderEntity createOrderEntity, Long orderId) {
        return createOrderEntity.getOrderItemList().stream().map(item -> {
            OrderItemPO orderItemPO = new OrderItemPO();
            orderItemPO.setOrderId(orderId);
            orderItemPO.setOrderItemId(IdWorker.getId());
            orderItemPO.setProductId(item.getProductId());
            orderItemPO.setProductType(item.getProductType());
            orderItemPO.setProductName(item.getProductName());
            orderItemPO.setSkuCode(item.getSkuCode());
            orderItemPO.setQuantity(item.getQuantity());
            orderItemPO.setSalePrice(item.getSalePrice());
            orderItemPO.setOriginAmount(item.getOriginalPrice());
            orderItemPO.setPayAmount(item.getSalePrice());
            orderItemPO.setPurchasePrice(item.getOriginalPrice());
            orderItemPO.setSellerId(createOrderEntity.getSellerId());
            orderItemPO.setCreateTime(new Date());
            orderItemPO.setCreateUser(-1L);
            return orderItemPO;
        }).collect(Collectors.toList());
    }

    private OrderPO buildOrder(CreateOrderEntity createOrderEntity) {
        OrderPO orderPO = new OrderPO();
        orderPO.setOrderId(IdWorker.getId());
        orderPO.setParentOrderId(null);
        orderPO.setOuterOrderId(null);
        orderPO.setTotalAmount(createOrderEntity.getOrderAmount());
        orderPO.setPayAmount(createOrderEntity.getOrderAmount());
        orderPO.setCouponId(createOrderEntity.getCouponId());
        orderPO.setSellerId(createOrderEntity.getSellerId());
        orderPO.setUserId(createOrderEntity.getUserId());
        orderPO.setOrderTime(new Date());
        orderPO.setPayType(2);
        orderPO.setStatus(OrderStatus.CREATED.getCode());
        orderPO.setPayStatus(PayStatus.UNPAID.getCode());
        orderPO.setCreateTime(new Date());
        orderPO.setCreateUser(-1L);
        return orderPO;
    }
}
